package com.yeqiangwei.commons.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * 
 * @author aroot
 *
 */
public class Pagination implements java.io.Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -1524916060244511611L;

	private static final Log LOG = LogFactory.getLog(Pagination.class);
	
	private static final String PAGE = "page";

	public static final int MAX_RESULTS = 20;

	private Integer page = 1; // 当前页

	private Integer firstResult = 0;

	private Integer maxResults = 30;

	private Integer lastPage = 0; // 最后一页

	private Integer pageNode = 3; // 节点

	private Integer total = 0;
	
	private Integer num1 = 2;

	private String propertyName = "page";

	private Map<String, Object> elements; // 跳转页面的隐藏元素

	private HttpServletRequest request;
	
	/**
	 * 
	 * @param page
	 * @param maxResults
	 */
	public Pagination(Integer page, int maxResults) {
		if(page == null) {
			page = 1;
		}
		this.page = page;
		this.maxResults = maxResults;
		this.firstResult = (this.page - 1) * this.maxResults;
	}

	public Pagination(Long page, int maxResults) {
		this(TypeChange.objectToInteger(page, 1), maxResults);
	}

	public Pagination(HttpServletRequest request, int maxResults) {
		this(ParamHelper.getInteger(request, PAGE, 1), maxResults);
		this.request = request;
	}

	public String toString(String uri_begin, String uri_end) {
		String ajaxMethodName = ParamHelper.getString(request, "ajaxMethodName", null);
		if(LOG.isDebugEnabled()) {
			LOG.debug("page = " + page 
					+ ", maxResults = " + maxResults 
					+ ", total = " + total 
					+ ", uri_begin = " + uri_begin 
					+ ", uri_end = " + uri_end);
		}
		if ((page < 1 || maxResults < 1 || total < 1) || total <= maxResults) {
			return StringHelper.EMPTY;
		}
		StringBuilder sb = new StringBuilder();
		int start = 1, end = pageNode;
		int pages = getLastPage();
		/* 当前页超过总页数 */
		if (page > pages) {
			page = pages;
			end = pages;
			start = end - pageNode - 1;
		}
		/* 当前页大于指定显示的跳转页数 */
		if (page >= pageNode) {
			end = page + pageNode;
			start = page - (pageNode - num1);
			if (end > pages) {
				end = pages;
			}
			start = page - (pageNode - num1);
			if (end > pages) {
				end = pages;
			}
		}
		sb.append("<div class=\"pagination\">");
		sb.append("<form id=\"propertyName\" name=\"propertyName\" method=\"get\" action=\"\">");
		if (pages - start < pageNode && page > pageNode) {
			start = pages - (pageNode - num1);
		}
		if (end >= pages) {
			end = pages;
			start = end - pageNode - 1;
			if (start <= 0) {
				start = 1;
			}
		}
		if (start > 2) {
			sb.append("<a href=\"");
			sb.append(uri_begin);
			sb.append("1");
			sb.append(uri_end);
			sb.append("\"");
			if (!ValidatorHelper.isEmpty(ajaxMethodName)) {
				sb.append(" onclick=\"return ");
				sb.append(ajaxMethodName);
				sb.append("('");
				sb.append(uri_begin);
				sb.append("1");
				sb.append(uri_end);
				sb.append("');\"");
			}
			sb.append(">1...</a>");
		} else if (start == 2) {
			sb.append("<a href=\"");
			sb.append(uri_begin);
			sb.append("1");
			sb.append(uri_end);
			sb.append("\"");
			if (!ValidatorHelper.isEmpty(ajaxMethodName)) {
				sb.append(" onclick=\"return ");
				sb.append(ajaxMethodName);
				sb.append("('");
				sb.append(uri_begin);
				sb.append("1");
				sb.append(uri_end);
				sb.append("');\"");
			}
			sb.append(">1</a>");

		}
		for (int i = start; i <= end; i++) {
			if (i == page) {
				sb.append("<span class=\"slt\">");
				sb.append(i);
				sb.append("</span>");
			} else {
				sb.append("<a href=\"");
				sb.append(uri_begin);
				sb.append(i);
				sb.append(uri_end);
				sb.append("\"");
				if (!ValidatorHelper.isEmpty(ajaxMethodName)) {
					sb.append(" onclick=\"return ");
					sb.append(ajaxMethodName);
					sb.append("('");
					sb.append(uri_begin);
					sb.append(i);
					sb.append(uri_end);
					sb.append("');\"");
				}
				sb.append(">");
				sb.append(i);
				sb.append("</a>");
			}
		}
		// 提供最后一页
		if (end < pages) {
			sb.append("<a href=\"");
			sb.append(uri_begin);
			sb.append(pages);
			sb.append(uri_end);
			sb.append("\"");
			if (!ValidatorHelper.isEmpty(ajaxMethodName)) {
				sb.append(" onclick=\"return ");
				sb.append(ajaxMethodName);
				sb.append("('");
				sb.append(uri_begin);
				sb.append(pages);
				sb.append(uri_end);
				sb.append("');\"");
			}
			sb.append(">...");
			sb.append(pages);
			sb.append("</a>");
		}
		if (page < pages) {
			int nextpage = page + 1;
			sb.append("<a class=\"nxt\" href=\"");
			sb.append(uri_begin);
			sb.append(nextpage);
			sb.append(uri_end);
			sb.append("\"");
			if (!ValidatorHelper.isEmpty(ajaxMethodName)) {
				sb.append(" onclick=\"return ");
				sb.append(ajaxMethodName);
				sb.append("('");
				sb.append(uri_begin);
				sb.append(nextpage);
				sb.append(uri_end);
				sb.append("');\"");
			}
			sb.append(">");
			sb.append("下一页</a>");
		}
		if (!ValidatorHelper.isEmpty(elements)) {
			Iterator<String> it = elements.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				sb.append("<input type=\"hidden\" id=\"");
				sb.append(key);
				sb.append("\" name=\"");
				sb.append(key);
				sb.append("\" value=\"");
				sb.append(elements.get(key));
				sb.append("\" />");
			}
		}
		sb.append("</form></div>");
		return sb.toString();
	}
	
	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public String getPropertyName() {
		return propertyName;
	}

	public void setPropertyName(String propertyName) {
		this.propertyName = propertyName;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public Integer getLastPage() {
		if (maxResults == 0 || maxResults > total) {
			return 1;
		}
		if (total % maxResults != 0) {
			lastPage = (int) (total / maxResults + 1);
		} else {
			lastPage = (int) (total / maxResults);
		}
		if (lastPage < 1) {
			lastPage = 1;
		}
		if(lastPage > 999) {
			lastPage = 999;
		}
		return lastPage;
	}

	public void setLastPage(Integer lastPage) {
		this.lastPage = lastPage;
	}

	public int getPageNode() {
		return pageNode;
	}

	public void setPageNode(int pageNode) {
		this.pageNode = pageNode;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getMaxResults() {
		return maxResults;
	}

	public void setMaxResults(int maxResults) {
		this.maxResults = maxResults;
	}

	public int getStartRows() {
		return getFirstResult();
	}

	public int getFirstResult() {
		this.firstResult = (page - 1) * this.maxResults;
		return firstResult;
	}

	public void setFirstResult(int firstResult) {
		this.firstResult = firstResult;
	}

	public Map<String, Object> getElements() {
		return elements;
	}

	public void setElements(Map<String, Object> elements) {
		this.elements = elements;
	}
	
	private List<Order> orderList;
	
	
	public List<Order> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<Order> orderList) {
		this.orderList = orderList;
	}

	public void setOrderList(Order[] orders) {
		if(orders == null) {
			return ;
		}
		if(orderList == null ){
			orderList = new ArrayList<Order>();
		}
		for(Order order : orders) {
			orderList.add(order);
		}
	}
	
	public static final Order getNewOrder(String name, Boolean ascending) {
		return new Order(name, ascending);
	}
	
	public static class Order {
		
		public static final Boolean ASCENDING = Boolean.TRUE;
		public static final Boolean DESCENDING = Boolean.FALSE;
		
		public Order(String name, Boolean ascending){
			this.name = name;
			this.ascending = ascending;
		}
		
		private String name;
		private Boolean ascending;
		
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public Boolean getAscending() {
			return ascending;
		}
		public void setAscending(Boolean ascending) {
			this.ascending = ascending;
		}
	}
}
